package com.eunion.core.common.jpa.query;

import java.util.Optional;
import java.util.function.Consumer;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import com.eunion.core.common.query.QueryContainer;

public final class RequestQueryRequirement<Entity, Bean> implements QueryRequirement<Entity, Bean> {

    private static final long serialVersionUID = 1L;

    private final QueryContainer<Entity> queryBean;

    private final Optional<Consumer<Root<Entity>>> fectchStrategy;

    public RequestQueryRequirement(QueryContainer<Entity> queryBean) {
        this(queryBean, null);
    }

    public RequestQueryRequirement(QueryContainer<Entity> queryBean, Consumer<Root<Entity>> fectchStrategy) {
        this.queryBean = queryBean;
        this.fectchStrategy = Optional.ofNullable(fectchStrategy);
    }

    @Override
    public void applyFetches(Root<Entity> root) {
        if (fectchStrategy.isPresent()) {
            fectchStrategy.get().accept(root);
        }
    }

    @Override
    public Predicate where(Root<Entity> root, CriteriaQuery<Bean> query, CriteriaBuilder cb) {
        return Optional.ofNullable(queryBean).map(q -> q.toPredicate(root, cb)).orElse(null);
    }

}
